//Copyright (c) 2010 Jimmy Merari - jim.merari@gmail.com

//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:

//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.

//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.

using System;
using System.Data;
using System.Web;
using System.Collections;

namespace Cinovasi.Scriptagility
{
    public class ScriptInclude : IHttpHandler
    {
        private int m_ModuleId = 0;
        private int m_TabId = 0;
        private string m_ScriptName = string.Empty;
        private bool m_Debug = false;
        private string m_ContentType = "text/plain";

        private int ModuleId
        {
            get
            {
                if(m_ModuleId == 0)
                {
                    string strModuleId = HttpContext.Current.Request.QueryString["moduleId"];
                    if(strModuleId != null)
                    {
                        int.TryParse(strModuleId, out m_ModuleId);
                    }
                }
                return m_ModuleId;
            }
        }

        private int TabId
        {
            get
            {
                if(m_TabId == 0)
                {
                    string strTabId = HttpContext.Current.Request.QueryString["tabId"];
                    if(strTabId != null)
                    {
                        int.TryParse(strTabId, out m_TabId);
                    }
                }
                return m_TabId;
            }
        }

        private string ScriptName
        {
            get
            {
                if(m_ScriptName == string.Empty)
                {
                    string scriptName = HttpContext.Current.Request.QueryString["scriptName"];
                    if(scriptName != null)
                    {
                        m_ScriptName = scriptName;
                    }
                }
                return m_ScriptName;
            }
        }

        private bool Debug
        {
            get
            {
                if(m_Debug == false)
                {
                    string strDebug = HttpContext.Current.Request.QueryString["debug"];
                    if(strDebug != null && strDebug.Equals("1"))
                        m_Debug = true;
                }
                return m_Debug;
            }
        }

        public void ProcessRequest(HttpContext context)
        {
            string script = RenderScript();

            if (!Debug)
            {
                //script = JavaScriptCompressor.Compress(script, true, true, true, false, 4095);
                script = new JsMin().Minify(script);
            }

            context.Response.ContentType = "application/x-javascript";
            context.Response.AppendHeader("Content-Length", script.Length.ToString());
            context.Response.Write(script);
            context.Response.Flush();
            context.Response.Close();
        }

        private string RenderScript()
        {
            DotNetNuke.Services.Tokens.TokenReplace tr = new DotNetNuke.Services.Tokens.TokenReplace(DotNetNuke.Services.Tokens.Scope.Debug);
            tr.User = DotNetNuke.Entities.Users.UserController.GetCurrentUserInfo();
            DotNetNuke.Entities.Modules.ModuleController mc = new DotNetNuke.Entities.Modules.ModuleController();
            tr.ModuleInfo = mc.GetModule(ModuleId, TabId);
            tr.ModuleId = ModuleId;
            tr.PortalSettings = DotNetNuke.Entities.Portals.PortalController.GetCurrentPortalSettings();

            System.Text.StringBuilder sb = new System.Text.StringBuilder();

            if (ScriptName.Length != 0) //only one specific script requested
            {
                ScriptInfo si = ScriptInfo.GetExternalScriptByName(ModuleId, ScriptName);
                if (si != null && si.Script.Length != 0)
                {
                    string script = si.Script;
                    if (si.EnableTokenReplace)
                    {
                        script = tr.ReplaceEnvironmentTokens(script);
                    }
                    script = script.Replace("{{SYS:AppRoot}}", HttpContext.Current.Request.ApplicationPath);
                    sb.AppendLine(script);
                    if (si.ContentType.Length != 0) m_ContentType = si.ContentType;
                }
            }
            else
            {
                ArrayList scripts = ScriptInfo.GetExternalScriptByModuleId(ModuleId);
                foreach (ScriptInfo si in scripts)
                {
                    if (si.Script.Length == 0) continue;

                    string script = si.Script;
                    if (si.EnableTokenReplace)
                    {
                        script = tr.ReplaceEnvironmentTokens(script);
                    }
                    script = script.Replace("{{SYS:AppRoot}}", HttpContext.Current.Request.ApplicationPath);

                    sb.AppendLine(script);
                    if (si.ContentType.Length != 0) m_ContentType = si.ContentType; //the last non-empty contentType will rules
                }
            }
            return sb.ToString();
        }


        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}
